package com.geo.auth.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import com.geo.auth.dto.LoginRequest;
import com.geo.auth.dto.LoginResponse;
import com.geo.auth.dto.RegisterRequest;
import com.geo.auth.dto.UserInfoResponse;
import com.geo.auth.entity.User;
import com.geo.auth.service.AuthService;
import com.geo.common.result.Result;
import com.geo.common.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;

/**
 * 认证相关API控制器
 * 
 * @author GEO Team
 * @version 1.0
 */
@Slf4j
@RestController
@RequestMapping("/api/auth")
@Validated
public class AuthController {
    
    private static final Logger log = LoggerFactory.getLogger(AuthController.class);
    
    @Autowired
    private AuthService authService;
    
    /**
     * 用户登录
     * @param request 登录请求
     * @param httpRequest HTTP请求
     * @return 登录响应
     */
    @SaIgnore
    @PostMapping("/login")
    public Result<LoginResponse> login(@Valid @RequestBody LoginRequest request, 
                                      HttpServletRequest httpRequest) {
        try {
            // 获取客户端IP
            String clientIp = getClientIpAddress(httpRequest);
            request.setClientIp(clientIp);
            
            LoginResponse response = authService.login(request);
            
            log.info("用户登录成功: {}", request.getUsername());
            return Result.success(response);
            
        } catch (Exception e) {
            log.error("用户登录失败: {}", request.getUsername(), e);
            return Result.error(ResultCode.INVALID_CREDENTIALS, e.getMessage());
        }
    }
    
    /**
     * 用户注册
     * @param request 注册请求
     * @return 注册响应
     */
    @SaIgnore
    @PostMapping("/register")
    public Result<String> register(@Valid @RequestBody RegisterRequest request) {
        try {
            User user = authService.register(request);
            
            log.info("用户注册成功: {}", request.getUsername());
            return Result.success("注册成功", user.getId());
            
        } catch (Exception e) {
            log.error("用户注册失败: {}", request.getUsername(), e);
            return Result.error(ResultCode.USER_ALREADY_EXISTS, e.getMessage());
        }
    }
    
    /**
     * 用户登出
     * @return 登出响应
     */
    @PostMapping("/logout")
    public Result<String> logout() {
        try {
            authService.logout();
            return Result.success("登出成功");
            
        } catch (Exception e) {
            log.error("用户登出失败", e);
            return Result.error(ResultCode.FAILURE, "登出失败");
        }
    }
    
    /**
     * 获取当前用户信息
     * @return 用户信息
     */
    @GetMapping("/userinfo")
    public Result<UserInfoResponse> getCurrentUser() {
        try {
            UserInfoResponse userInfo = authService.getCurrentUser();
            return Result.success(userInfo);
            
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
            return Result.error(ResultCode.USER_NOT_FOUND, e.getMessage());
        }
    }
    
    /**
     * 刷新令牌
     * @return 新的令牌信息
     */
    @PostMapping("/refresh")
    public Result<String> refreshToken() {
        try {
            // Sa-Token会自动处理令牌刷新
            return Result.success("令牌刷新成功");
            
        } catch (Exception e) {
            log.error("令牌刷新失败", e);
            return Result.error(ResultCode.TOKEN_EXPIRED, "令牌刷新失败");
        }
    }
    
    /**
     * 检查用户名是否可用
     * @param username 用户名
     * @return 是否可用
     */
    @SaIgnore
    @GetMapping("/check-username")
    public Result<Boolean> checkUsername(@RequestParam String username) {
        try {
            // 这里应该调用service检查用户名是否存在
            // 简化实现，实际应该在AuthService中添加相应方法
            return Result.success("用户名检查完成", true);
            
        } catch (Exception e) {
            log.error("检查用户名失败", e);
            return Result.error(ResultCode.FAILURE, "检查用户名失败");
        }
    }
    
    /**
     * 发送验证码（用于密码重置等）
     * @param email 邮箱地址
     * @return 发送结果
     */
    @SaIgnore
    @PostMapping("/send-verification-code")
    public Result<String> sendVerificationCode(@RequestParam String email) {
        try {
            // 这里应该实现验证码发送逻辑
            log.info("向邮箱发送验证码: {}", email);
            return Result.success("验证码发送成功");
            
        } catch (Exception e) {
            log.error("发送验证码失败", e);
            return Result.error(ResultCode.FAILURE, "发送验证码失败");
        }
    }
    
    /**
     * 重置密码
     * @param email 邮箱
     * @param code 验证码
     * @param newPassword 新密码
     * @return 重置结果
     */
    @SaIgnore
    @PostMapping("/reset-password")
    public Result<String> resetPassword(@RequestParam String email,
                                       @RequestParam String code,
                                       @RequestParam String newPassword) {
        try {
            // 这里应该实现密码重置逻辑
            log.info("重置密码请求: {}", email);
            return Result.success("密码重置成功");
            
        } catch (Exception e) {
            log.error("重置密码失败", e);
            return Result.error(ResultCode.FAILURE, "重置密码失败");
        }
    }
    
    /**
     * 获取客户端IP地址
     * @param request HTTP请求
     * @return IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0];
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
}